<template>
  <div class="editorWrap flex-column">

    <div
      ref="editor"
      :autofocus="this.autofocus"
      @focus="editorFocus"
      @blur="editorBlur"
      @paste="textPaste"
      class="richTextEditor autoGrow"
      contenteditable="true">
    </div>
    <div class="placeholder" v-if="showPlacehoder">{{placeholder}}</div>
    <div :class="['emojiContainer','flex-row',emojiPos!='top' && 'bottomPos']" v-show="showEmoji">
      <!-- {{ emojis }} -->
      <div v-for="(emoji, i) in emojis" :key="i" class="face" @click.prevent="chooseEmoji(emoji)">
        <img :src="emoji.img" alt="">
      </div>
    </div>
    <div class="tools flex-row">
      <div class="emojiSwitch" v-if="withEmoji" @click="toggleEmojiContainer"></div>
      <button class="layui-btn layui-btn-xs" v-if="withButton" @click="submit">{{buttonText}}</button>
    </div>
  </div>
</template>
<script>
import { emotions } from '@/lib/wechat-emoji'


function hasParent(node,dom) {
  let _node = node
  let rs = false
  while (1){
    if(!_node.parentElement){
      break;
    }
    if(_node != dom ){
      _node = _node.parentElement
    } else if(_node === dom){
      rs = true
      break;
    }
  }
  return rs
}

export default {
  name: 'richTextEditor',
  data() {
    return {
      editor: '',
      showEmoji: '',
      showPlacehoder: true,
      lastSelection: null,
      //lastFocusNode:null,
      emojis:emotions,
    }
  },
  created() {

  },
  props: {
    placeholder: {
      type: String,
      default: ''
    },
    autofocus: {
      type: Boolean,
      default: true,
    },
    withButton: {
      type: Boolean,
      default: true,
    },
    withEmoji: {
      type: Boolean,
      default: true,
    },
    buttonText: {
      type: String,
      default: '发送'
    },
    emojiPos: {
      type: String,
      default: 'top'
    }
  },
  mounted() {
    document.execCommand("defaultParagraphSeparator", false, "p");
    this.editor = this.$refs.editor
    document.addEventListener('selectionchange',(e)=>{
      let sel = window.getSelection()

      if(hasParent(sel.focusNode,this.$refs.editor)){
        this.lastRange = sel.getRangeAt(0)
        this.lastSelection = sel

      }

    })
  },
  methods: {
    editorFocus() {
      this.showPlacehoder = false
    },
    editorBlur() {
      const children = this.editor.childNodes
      const empty = !children.length || children.length==1&&children[0].nodeName=='#comment'
      if (empty) {
        this.showPlacehoder = true
      } else {
        this.showPlacehoder = false
      }
    },
    toggleEmojiContainer( ) {
      this.showEmoji = !this.showEmoji
    },
    chooseEmoji(item) {
      console.log()
      const lastRange = this.lastRange
      const src = item.img
      this.showEmoji = false

      const sel = this.lastSelection || window.getSelection();
      const range = document.createRange();
      const el = document.createElement("img");
      el.src = src;
      el.alt = item.text
      el.classList.add('emoji')

      if(!lastRange){

        this.$refs.editor.appendChild(el)
        this.$refs.editor.focus()
        range.selectNodeContents(this.$refs.editor)
        range.collapse()
        sel.removeAllRanges();
        sel.addRange(range);
        return
      }

      const nextText = document.createTextNode('')
      //
      lastRange.setStart(lastRange.endContainer, lastRange.endOffset) // 设置开始插入位置
      lastRange.insertNode(el) // 插入元素，node节点

      lastRange.setEnd(lastRange.endContainer, lastRange.endOffset) // 设置结束位置

      lastRange.setStart(lastRange.endContainer, lastRange.endOffset)
      lastRange.insertNode(nextText)
      lastRange.setEnd(lastRange.endContainer, lastRange.endOffset)

      this.$refs.editor.focus()
      window.getSelection().selectAllChildren(nextText)

    },
    setEditorValue(val) {
      this.editor.focus()
      this.$nextTick(()=>{
        this.editor.append(val);
        const sel = this.lastSelection || window.getSelection();
        const range = document.createRange();
        range.selectNodeContents(this.editor)
        range.collapse()
        sel.removeAllRanges();
        sel.addRange(range);
      })
    },
    clear(){
      this.editor.innerHTML=''
    },
    getEditorValue() {
      const content = this.walkChildNodes(this.editor.childNodes, '');

      // return console.log(JSON.stringify(content))
      return content;
    },
    walkChildNodes(childNodes, content) {
      Array.from(childNodes).map(child=>{
        let nodeName = child.nodeName
        let outerHTML = child.outerHTML
        if (nodeName=='#text') {
          content += child.nodeValue
        } else if (nodeName=='IMG') {
          content += `[${child.alt}]`
        } else if (nodeName=='DIV') {
          if(outerHTML == '<div><br></div>'){
            content += '\n'
          }else{
            content += '\n'
            content += (this.walkChildNodes(child.childNodes, '')||'')
          }

        } else if (nodeName=='SPAN'){
          content += this.walkChildNodes(child.childNodes, '')
        } else if (nodeName=='BR') {
          content += '\n'
        } else if (nodeName=='P'){
          if(outerHTML == '<p><br></p>'){
            content += '\n'
          }else{
            content += '\n'
            content += (this.walkChildNodes(child.childNodes, '')||'')
          }
        }
      })
      return content
    },
    submit() {
      let content = '';
      if (!this.showPlacehoder) {
        content = this.getEditorValue()
      }
      this.$emit('submit', content);
    },
    textPaste(e){
      e.preventDefault()
      this._textPaste(e.clipboardData)
    },
    _textPaste(dataTransfer){
      const text = Array.from(dataTransfer.items)[0]
      if(text){
        text.getAsString((str)=>{
          let selection = window.getSelection()
          let range = selection.getRangeAt(0)
          const atNode = document.createElement('span')
          atNode.innerHTML=str
          range.setStart(range.endContainer, range.endOffset) // 设置开始插入位置
          range.insertNode(atNode) // 插入元素，node节点
          range.setEnd(range.endContainer, range.endOffset) // 设置结束位置
          selection.selectAllChildren(this.$refs.editor) //选择容器
          selection.collapse(atNode,1)
        })
      }
    },
  }
}
</script>
<style scoped>
.richTextEditor{
  position: relative;
  z-index: 1;
}
.placeholder{
  position: absolute;
  top: 0;
  left: 0;
  padding: 6px;
  color: #666
}
.editorWrap .emojiContainer{z-index: 1;}
</style>
